package com.swind.fast.modules.app.halali.partner.service.impl;

import com.swind.fast.common.util.oConvertUtils;

import com.swind.fast.modules.app.halali.partner.entity.RestaurantMeal;
import com.swind.fast.modules.app.halali.partner.entity.RestaurantCategory;
import com.swind.fast.modules.app.halali.partner.entity.RestaurantMealCategory;

import com.swind.fast.modules.app.halali.partner.mapper.RestaurantMealMapper;
import com.swind.fast.modules.app.halali.partner.service.IRestaurantMealService;
import com.swind.fast.modules.app.halali.partner.service.IRestaurantMealCategoryService;

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;

import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.date.DateBetween;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;

import javax.annotation.Resource;

import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Comparator;
import com.swind.fast.modules.app.halali.partner.vo.response.MealInfoVo;
import com.swind.fast.modules.app.halali.partner.vo.request.MealVo;
import org.springframework.beans.BeanUtils;
import org.apache.shiro.SecurityUtils;
import com.swind.fast.common.system.vo.HalaliLoginUser;
import com.swind.fast.modules.app.halali.partner.vo.request.RankInfoVo;
import org.springframework.beans.factory.annotation.Value;
import java.util.Optional;
import com.swind.fast.modules.app.halali.partner.vo.common.CategoryVo;
import com.swind.fast.modules.app.halali.partner.service.IRestaurantCategoryService;

/**
 * @Description: 项目
 * @Author: swind
 * @Date:   2021-11-20
 * @Version: V1.0
 */
@Slf4j
@Service
public class RestaurantMealServiceImpl extends ServiceImpl<RestaurantMealMapper, RestaurantMeal> implements IRestaurantMealService {

    @Value(value = "${swind.path.preview}")
    private String previewPath;

    @Autowired
    private IRestaurantMealCategoryService mealCategoryService;

    @Autowired
    private IRestaurantCategoryService restaurantCategoryService;

    public RestaurantMeal getDetailById(String id) {
        RestaurantMeal result = this.getById(id);
        List<RestaurantMealCategory> catList = this.baseMapper.getRestaurantMealCategoryList(id);
        List<String> catIds = catList.stream().map(RestaurantMealCategory::getRestaurantCategoryId).collect(Collectors.toList());
        List<CategoryVo> categories = new ArrayList<CategoryVo>();
        if (oConvertUtils.listIsNotEmpty(catIds)) {
            List<RestaurantCategory> restCatList = this.restaurantCategoryService.listByIds(catIds);
            for (RestaurantCategory cat : restCatList) {
                categories.add(oConvertUtils.entityToModel(cat, CategoryVo.class));
            }
        }
        result.setCategories(categories);
        return result;
    }

    public List<RestaurantCategory> getMealListv3() {
        // 待返回的列表
        List<RestaurantCategory> retlist = new ArrayList<RestaurantCategory>();
        HalaliLoginUser sysUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        String id = sysUser.getRestaurantId();
        if (oConvertUtils.isEmpty(id)) {
            return retlist;
        }
        List<RestaurantCategory> catList = this.baseMapper.getRestaurantCategoryList(id);
        List<RestaurantMeal> tlist = this.baseMapper.getMealList(id);
        this.renderPicList(tlist);

        if (oConvertUtils.listIsEmpty(tlist)) {
            return retlist;
        }

        List<String> tlistIds = tlist.stream().map(RestaurantMeal::getId).collect(Collectors.toList());
        // 获取餐厅餐品分类
        QueryWrapper<RestaurantMealCategory> pqueryWrapper = new QueryWrapper<RestaurantMealCategory>().in("meal_id", tlistIds);
        List<RestaurantMealCategory> plist = mealCategoryService.list(pqueryWrapper);
        List<String> plistIds = plist.stream().map(RestaurantMealCategory::getId).collect(Collectors.toList());
        List<String> plistCategoryIds = plist.stream().map(RestaurantMealCategory::getRestaurantCategoryId).collect(Collectors.toList());
        List<RestaurantCategory> pfinallist = catList.stream().filter(e -> plistCategoryIds.contains(e.getId())).collect(Collectors.toList());
        for (RestaurantCategory category : pfinallist) {
            List<RestaurantMealCategory> citems = plist.stream().filter(e -> e.getRestaurantCategoryId().equals(category.getId())).collect(Collectors.toList());
            List<String> mealIds = citems.stream().map(RestaurantMealCategory::getMealId).distinct().collect(Collectors.toList());
            // 获取该类别下所有餐品详情
            List<RestaurantMeal> flist = tlist.stream().filter(e -> (mealIds.contains(e.getId()))).collect(Collectors.toList());

            // 获取一个分类UniqId
            List<RestaurantMeal> mealList = new ArrayList<RestaurantMeal>();
            for (RestaurantMeal cmeal : flist) {
                RestaurantMeal nmeal = oConvertUtils.entityToModel(cmeal, RestaurantMeal.class);
                nmeal.setMealId(nmeal.getId());
                Optional<RestaurantMealCategory> itemOpt = citems.stream()
                        .filter(p -> p.getMealId().equals(nmeal.getId()))
                        .findFirst();
                if (itemOpt.isPresent()) {
                    RestaurantMealCategory cat = itemOpt.get();
                    nmeal.setUniqueId(cat.getId());
                    nmeal.setId(cat.getId());
                    nmeal.setRank(cat.getRank());
                    mealList.add(nmeal);
                }
            }
            List<RestaurantMeal> sortedList = mealList.stream()
                                       .sorted(Comparator.comparingInt(RestaurantMeal::getRank)) // 按长度排序
                                       .collect(Collectors.toList());
            category.setMeals(sortedList);
            RestaurantCategory fcategory = oConvertUtils.entityToModel(category, RestaurantCategory.class);
            retlist.add(fcategory);
        }

        return retlist;
    }

    public List<RestaurantCategory> getMealListv2() {
        // 待返回的列表
        List<RestaurantCategory> retlist = new ArrayList<RestaurantCategory>();

        HalaliLoginUser sysUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        String id = sysUser.getRestaurantId();
        if (oConvertUtils.isEmpty(id)) {
            return retlist;
        }

        List<RestaurantCategory> catList = this.baseMapper.getRestaurantCategoryList(id);
        List<String> catIds = catList.stream().map(RestaurantCategory::getId).collect(Collectors.toList());
        log.info("catList: {}", catIds);

        List<RestaurantMeal> tlist = this.baseMapper.getMealList(id);
        this.renderPicList(tlist);

        if (oConvertUtils.listIsNotEmpty(tlist)) {
            List<String> tlistIds = tlist.stream().map(RestaurantMeal::getId).collect(Collectors.toList());
            log.info("tlistIds: {}", tlistIds);
            // 获取餐厅餐品分类
            QueryWrapper<RestaurantMealCategory> pqueryWrapper = new QueryWrapper<RestaurantMealCategory>().in("meal_id", tlistIds);
            List<RestaurantMealCategory> plist = mealCategoryService.list(pqueryWrapper);
            List<String> plistIds = plist.stream().map(RestaurantMealCategory::getId).collect(Collectors.toList());
            log.info("plistIds: {}", plistIds);

            for (RestaurantCategory category : catList) {
                // log.info("categoryId: {}", category.getId());
                // 获取该类别下所有餐品
                List<RestaurantMealCategory> citems = plist.stream().filter(e -> e.getRestaurantCategoryId().equals(category.getId())).collect(Collectors.toList());
                // log.info("categoryId: {}, citems: {}", category.getId(), citems);
                // 获取该类别下所有餐品IDs
                List<String> mealIds = citems.stream().map(RestaurantMealCategory::getMealId).distinct().collect(Collectors.toList());
                // 获取该类别下所有餐品详情
                List<RestaurantMeal> flist = tlist.stream().filter(e -> (mealIds.contains(e.getId()))).collect(Collectors.toList());
                // log.info("flist: {}", flist);

                List<RestaurantMeal> retList = new ArrayList<RestaurantMeal>();
                // 获取一个分类UniqId
                for (RestaurantMeal cmeal : flist) {
                    cmeal.setMealId(cmeal.getId());
                    // Optional<RestaurantMealCategory> itemOpt = plist.stream().filter(p -> (p.getMealId().equals(cmeal.getId()) && p.getRestaurantCategoryId().equals(category.getId()))).findFirst();
                    // Optional<RestaurantMealCategory> itemOpt = plist.stream().filter(p -> p.getMealId().equals(cmeal.getId()) && p.getRestaurantCategoryId().equals(category.getId())).findFirst();
                    Optional<RestaurantMealCategory> itemOpt = citems.stream()
                        .filter(p -> p.getMealId().equals(cmeal.getId()))
                        .findFirst();

                    if (itemOpt.isPresent()) {
                        RestaurantMealCategory cat = itemOpt.get();
                        cmeal.setUniqueId(cat.getId());
                        cmeal.setId(cat.getId());
                        cmeal.setRank(cat.getRank());
                        // log.info("cmealId: {}, categoryId: {}, restCatId: {}, catId: {}, cmeal: {}", cmeal.getId(), category.getId(), cat.getRestaurantCategoryId(), cat.getId(), cmeal.getUniqueId());

                        RestaurantMeal nmeal = oConvertUtils.entityToModel(cmeal, RestaurantMeal.class);
                        retList.add(nmeal);
                    }
                }

                category.setMeals(retList);
                // log.info("category: {}", category);
                if (!oConvertUtils.isEmpty(flist)) {
                    retlist.add(category);
                }
            }
        }

        return retlist;
    }

    public List<RestaurantCategory> getMealListv1() {
        HalaliLoginUser sysUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        String id = sysUser.getRestaurantId();

        List<RestaurantCategory> catList = this.baseMapper.getRestaurantCategoryList(id);
        List<RestaurantMeal> tlist = this.baseMapper.getMealList(id);
        this.renderPicList(tlist);

        // 待返回的列表
        List<RestaurantCategory> retlist = new ArrayList<RestaurantCategory>();
        if (oConvertUtils.listIsNotEmpty(tlist)) {
            for (RestaurantCategory category : catList) {
                // 获取该类别下所有餐品详情
                List<RestaurantMeal> flist = tlist.stream().filter(e -> (e.getRestaurantCategoryId().equals(category.getId()))).collect(Collectors.toList());

                if (oConvertUtils.listIsNotEmpty(flist)) {
                    category.setItems(flist);
                    retlist.add(category);
                }
            }
        }
        return retlist;
    }

    public List<RestaurantMeal> getMealList() {
        HalaliLoginUser sysUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        String id = sysUser.getRestaurantId();
        List<RestaurantMeal> list = this.baseMapper.getMealList(id);
        this.renderPicList(list);
        return list;
    }

    public MealInfoVo saveMain(MealVo mealVo) {
        RestaurantMeal meal = new RestaurantMeal();
        oConvertUtils.copyPropertiesIgnoreNull(mealVo, meal);

        HalaliLoginUser sysUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        String restId = sysUser.getRestaurantId();
        meal.setRestaurantId(restId);

        this.save(meal);
        this.mealCategoryService.saveMealCategories(meal.getId(), mealVo);

        MealInfoVo mealInfo = new MealInfoVo();
        oConvertUtils.copyPropertiesIgnoreNull(meal, mealInfo);
        return mealInfo;
    }

    public MealInfoVo updateInfo(MealVo mealVo) {
        RestaurantMeal meal = this.getById(mealVo.getId());
        oConvertUtils.copyPropertiesIgnoreNull(mealVo, meal);

        this.updateById(meal);
        this.mealCategoryService.saveMealCategories(meal.getId(), mealVo);

        MealInfoVo mealInfo = new MealInfoVo();
        oConvertUtils.copyPropertiesIgnoreNull(meal, mealInfo);
        return mealInfo;
    }

    public void updateRank(List<RankInfoVo> items) {
        this.mealCategoryService.updateRank(items);
    }


    public void renderPic(RestaurantMeal meal) {
        if (oConvertUtils.isEmpty(meal.getPic()) || meal.getPic().startsWith("http")) {
            return;
        }
        String picPath = this.previewPath + "/" + meal.getPic();
        meal.setPic(picPath);
    }

    private void renderPicList(List<RestaurantMeal> meals) {
        for (RestaurantMeal meal : meals) {
            this.renderPic(meal);
        }
    }

}
